// File PQueue.java
// This class using a max-heap to implement a priority queue.
// This priority queue is to simulate the round robin cpu scheduling.

import java.util.*;

public class PQueue
{
    private MaxHeap mHeap;

    // Constructor.
    public PQueue()
    {
	mHeap = new MaxHeap();
    }

    public PQueue(Process p)
    {
	mHeap = new MaxHeap(p);
    }


    // return true if the priority is empty.
    // otherwise, return false.
    public boolean isEmpty(){
    	return mHeap.isEmpty();
    }

    
    // Insert a Process p into the priority queue.
    // POST: The process p is inserted into the 
    //       priority queue.
    public void enPQueue(Process p)
    {
    	mHeap.insert(p);
    }

    
    // PRE:  This Priority Queue should not be empty.
    // POST: Remove and return the process with the highest
    //       priority (in case of tie, pick the one
    //       with earliest arrival time)
    public Process dePQueue()
    {
    	return (Process)mHeap.remove();
    }

    
    // Return the number of processes currently in the priority queue.
    public int size()
    {
    	return mHeap.sizeOfHeap();
    }

    
    // Increment the timeNotProcessed by one for all processes in 
    // the priority queue. If a process's timeNotProcessed exceeds
    // timeToIncrementLevel and if its original priority is less
    // than maxLevel, then increment its priority by 1 and
    // reset the timeNotProcessed to 0.
    // Finally, restructure the PQueue to make it a heap again.
    public void update(int timeToIncrementLevel, int maxLevel)
    {
    	BTNode cursor;
    	Iterator itr = mHeap.heapItr();
    	while(itr.hasNext())
    	{
    		cursor = (BTNode)itr.next();   		
    		Process p = ((Process)cursor.getData());
    		if (p != null)
    		{
    		p.increaseTimeNotProcessed();
    		
    		if((((Process)(cursor.getData())).getPriority() < maxLevel ) 
    		&& (((Process)(cursor.getData())).getTimeNotProcessed() > timeToIncrementLevel))
    		{
    			((Process)(cursor.getData())).changePriority(((Process)(cursor.getData())).getPriority() + 1 );
    			((Process)(cursor.getData())).resetTimeNotProcessed();
    			mHeap.maxHeapifyUp(cursor);
    		}
    		}
    	}
    }
}